#include <emscripten.h>
#include <string>
#include "EyerGLCustomComponent/EyerGLCustomComponent.hpp"
#include "Scene.hpp"

#include "EyerVideoEditor/EyerVideoEditor.hpp"

extern "C" {
    #include "html5.h"
}


EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = NULL;

Eyer::Scene * scene = nullptr;

extern "C" {
	EMSCRIPTEN_KEEPALIVE
    void createContext (int width, int height, char * id){
		EyerLog("createContext width: %d, height: %d, id: %s\n", width, height, id);

		EmscriptenWebGLContextAttributes attrs;
		attrs.explicitSwapControl = 0;
		attrs.depth = 1;
		attrs.stencil = 1;
		attrs.antialias = 1;
		attrs.majorVersion = 2;
		attrs.minorVersion = 0;

		std::string id_str = id;
		std::string sharp_id_str = "#" + id_str;

		context = emscripten_webgl_create_context(sharp_id_str.c_str(), &attrs);
    	emscripten_webgl_make_context_current(context);

		// glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
		// glClearColor(0.8f, 0.8f, 0.8f, 1.0f);
		glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        // glCullFace(GL_BACK);
        // glFrontFace(GL_CW);

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		// emscripten_set_main_loop(main_loop, 0, true);
		// emscripten_webgl_destroy_context(context);
	}

	EMSCRIPTEN_KEEPALIVE
    void start (int width, int height){
        emscripten_webgl_make_context_current(context);
        scene = new Eyer::Scene(width, height);
        scene->Start();
	}

	EMSCRIPTEN_KEEPALIVE
    void update (){
        emscripten_webgl_make_context_current(context);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        scene->Update();
    }

    EMSCRIPTEN_KEEPALIVE
    void onmouse (int x, int y){
	    if(scene != nullptr){
	        scene->OnMouse(x, y);
	    }
    }

    EMSCRIPTEN_KEEPALIVE
    void onmousedown (int x){
        if(scene != nullptr){
            scene->OnMouseDown();
        }
    }

    EMSCRIPTEN_KEEPALIVE
    void onmouseup (int x){
        if(scene != nullptr){
            scene->OnMouseUp();
        }
    }

    EMSCRIPTEN_KEEPALIVE
    void onmouseover (int x){
        if(scene != nullptr){
            scene->OnMouseOver();
        }
    }

    EMSCRIPTEN_KEEPALIVE
    void onmouseout (int x){
        if(scene != nullptr){
            scene->OnMouseOut();
        }
    }

    EMSCRIPTEN_KEEPALIVE
    void onkeydown (int keycode){
        if(scene != nullptr){
            scene->OnKeyDown(keycode);
        }
    }
    EMSCRIPTEN_KEEPALIVE
    void onkeyup (int keycode){
        if(scene != nullptr){
            scene->OnKeyUp(keycode);
        }
    }

    EMSCRIPTEN_KEEPALIVE
    void setTimeRange (float start, float end){
        if(scene != nullptr){
            scene->SetTimeRange(start, end);
        }
    }
}

int main(int argc, char const *argv[]) {
	EyerLog("Loaded\n");

    EM_ASM(
        if (typeof window!="undefined") {
            window.dispatchEvent(new CustomEvent("wasmLoaded"))
        } else {
            global.onWASMLoaded && global.onWASMLoaded()
        }
    );

	return EXIT_SUCCESS;
}